package com.yaowk.sfp.utils.generator;

import com.yaowk.sfp.common.db.BaseServiceImpl;
import com.yaowk.sfp.common.db.GeneratorNote;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Data
@EqualsAndHashCode(callSuper = false)
public class ServiceBaseGenerator extends AbstractGenerator {

    private String classTemplate = "public abstract class %s extends BaseServiceImpl<%s, %s, %s> implements %s {%n%n";
    private String daoTemplate = "\t@Autowired%n\tprivate %s dao;%n%n\t@Override protected %s getDao() {%n\treturn dao;%n\t}%n%n";

    private ModelGenerator modelGenerator;
    private ServiceGenerator serviceGenerator;
    private DaoGenerator daoGenerator;

    public ServiceBaseGenerator() {
        setSuffix("ServiceBase");
    }


    @Override
    public void generator() throws Exception {
        List<Class> entities = getEntities();
        String packageName = getPackageName();
        if (StringUtils.isEmpty(packageName)) {
            return;
        }
        String path = GeneratorUtils.getPath(packageName, getBasePath());
        for (Class clazz : entities) {
            // 构建类名
            String className = buildClassName(clazz);
            File file = new File(path + "/" + className + ".java");
            String newClazz = packageName + "." + className;
            if (file.exists()) {
                file.delete();
            }
            StringBuilder stringBuilder = new StringBuilder();

            // 设置包名
            appendPackage(stringBuilder);

            // 组织引用类
            Set<String> imports = new HashSet<>();
            imports.add(BaseServiceImpl.class.getTypeName());
            imports.add(Autowired.class.getTypeName());
            String[] pk = GeneratorUtils.getGenericSuper(clazz);
            imports.add(pk[1]);
            imports.add(modelGenerator.buildClassType(clazz));
            imports.add(clazz.getTypeName());
            imports.add(serviceGenerator.buildClassType(clazz));
            imports.add(daoGenerator.buildClassType(clazz));


            // 生成entity2model model2entity save 方法
            StringBuilder entity2ModelBuilder = new StringBuilder();
            StringBuilder model2EntityBuilder = new StringBuilder();
//            StringBuilder saveBuilder = new StringBuilder();
            StringBuilder updateParamsBuilder = new StringBuilder();
            entity2ModelBuilder.append("\t@Override\n\tpublic ")
                    .append(modelGenerator.buildClassName(clazz))
                    .append(" entity2Model(")
                    .append(clazz.getSimpleName())
                    .append(" entity) {\n\t\t")
                    .append(modelGenerator.buildClassName(clazz))
                    .append(" model = null;\n\t\tif(isNotEmpty(entity)){\n\t\t\tmodel = new ")
                    .append(modelGenerator.buildClassName(clazz))
                    .append("();");
            model2EntityBuilder.append("\t@Override\n\tpublic ")
                    .append(clazz.getSimpleName())
                    .append(" model2Entity(")
                    .append(modelGenerator.buildClassName(clazz))
                    .append(" model) {\n\t\t")
                    .append(clazz.getSimpleName())
                    .append(" entity = null;\n\t\tif(isNotEmpty(model)){\n\t\t\tentity = new ")
                    .append(clazz.getSimpleName())
                    .append("();");
//            saveBuilder.append("\t@Override\n\tpublic ")
//                    .append(modelGenerator.buildClassName(clazz))
//                    .append(" save(")
//                    .append(modelGenerator.buildClassName(clazz))
//                    .append(" model) {\n\t\tif(model.isNew()){\n\t\t\tmodel = super.simpleSave(model);\n\t\t} else {\n\t\t\t")
//                    .append(clazz.getSimpleName())
//                    .append(" entity = dao.findOne(model.getId());");
            updateParamsBuilder.append("\t@Override\n\tpublic ")
                    .append(clazz.getSimpleName())
                    .append(" updateParams(")
                    .append(modelGenerator.buildClassName(clazz))
                    .append(" model) {\n\t\t")
                    .append(clazz.getSimpleName())
                    .append(" entity = dao.findOne(model.getId());");

            // id操作
            String fieldName = "id";
            if (GeneratorUtils.needId(clazz)) {
                entity2ModelBuilder.append("\n\t\t\tmodel.")
                        .append(GeneratorUtils.setter(fieldName))
                        .append("(entity.")
                        .append(GeneratorUtils.getter(fieldName))
                        .append("());");
                model2EntityBuilder.append("\n\t\t\tentity.")
                        .append(GeneratorUtils.setter(fieldName))
                        .append("(model.")
                        .append(GeneratorUtils.getter(fieldName))
                        .append("());");
            }

            Field[] fields = getAllFields(clazz);

            for (Field field : fields) {
                GeneratorNote generatorNote = field.getAnnotation(GeneratorNote.class);
                if (ObjectUtils.isEmpty(generatorNote)) {
                    continue;
                }
//                ManyToOne manyToOne = field.getAnnotation(ManyToOne.class);
                String[] fieldType = GeneratorUtils.parseClassType(field.getType().getTypeName());
                fieldName = field.getName();
//                if (!ObjectUtils.isEmpty(manyToOne)) {
//                    fieldType = GeneratorUtils.getGenericSuper(field.getType());
//                    fieldName = fieldName + "Id";
//                }

                imports.add(fieldType[1]);
                entity2ModelBuilder.append("\n\t\t\tmodel.")
                        .append(GeneratorUtils.setter(fieldName))
                        .append("(entity.")
                        .append(GeneratorUtils.getter(fieldName))
                        .append("());");
                model2EntityBuilder.append("\n\t\t\tentity.")
                        .append(GeneratorUtils.setter(fieldName))
                        .append("(model.")
                        .append(GeneratorUtils.getter(fieldName))
                        .append("());");
                updateParamsBuilder.append("\n\t\tif(isNotEmpty(model.")
                        .append(GeneratorUtils.getter(fieldName))
                        .append("()))\n\t\t\tentity.")
                        .append(GeneratorUtils.setter(fieldName))
                        .append("(model.")
                        .append(GeneratorUtils.getter(fieldName))
                        .append("());");
            }

            entity2ModelBuilder.append("\n\t\t}\n\t\treturn model;\n\t}\n\n");
            model2EntityBuilder.append("\n\t\t}\n\t\treturn entity;\n\t}\n\n");
            updateParamsBuilder.append("\n\t\treturn entity;\n\t}\n\n");

            appendImport(stringBuilder, imports);

            //设置类
            stringBuilder.append(String.format(classTemplate, className, modelGenerator.buildClassName(clazz), clazz.getSimpleName(), pk[0], serviceGenerator.buildClassName(clazz)));
            // 设置dao
            stringBuilder.append(String.format(daoTemplate, daoGenerator.buildClassName(clazz), daoGenerator.buildClassName(clazz)));
            stringBuilder.append(entity2ModelBuilder);
            stringBuilder.append(model2EntityBuilder);
            stringBuilder.append(updateParamsBuilder);
            stringBuilder.append("\n}");

            // 执行生成
            GeneratorUtils.write(file, stringBuilder);

            System.out.println(newClazz);
        }
    }
}
